import os
import shutil
import threading
import uuid

import allure
import pytest
from PIL import Image

import settings
from common.core.globals import p
from common.core.page import BasePage


# 加载所有的page
@pytest.fixture(scope="session", autouse=True)
def load_all_pages():
    from common.core.globals import PageRouterManager
    import page_comps
    PageRouterManager.load_all_pages()  # 加载页面
    page_comps.load_all_components()  # 加载页面组件


class TestProcess:
    @staticmethod
    def _new_img_dir():
        d = os.path.join(settings.TMP_DIR, str(uuid.uuid4()))
        if not os.path.exists(d):
            os.makedirs(d)
        return d

    # 拼接成 git
    def _save_process(self):
        if not (img_list := os.listdir(self._img_dir)):
            return
        img_list.sort(key=lambda x: int(x[:-4]))
        first_image = Image.open(os.path.join(self._img_dir, img_list[0]))
        rest_images = [Image.open(os.path.join(self._img_dir, img)) for img in img_list[1:]]
        gif = os.path.join(self._img_dir, "okk.gif")
        first_image.save(gif, append_images=rest_images, duration=200, save_all=True, loop=0)  # 循环播放可以加上loop=0
        allure.attach.file(gif, "测试回放", allure.attachment_type.GIF)

    def __init__(self, page: BasePage, logging_process: bool):
        self._page = page
        self._logging_process = logging_process
        self._img_index = 0
        self._img_dir = self._new_img_dir()
        self._screen_event = threading.Event()
        self._screen_event.set()

    def _recording(self, driver):
        while True:
            if not self._screen_event.is_set():  # 截图事件保持激活
                break
            save_path = os.path.join(self._img_dir, str(self._img_index) + ".png")
            self._img_index += 1
            try:
                driver.get_screenshot_as_file(save_path)
            except Exception as e:
                del e

    def start_record(self) -> BasePage:
        # 当前测试线程内，webdriver 必须一致
        threading.Thread(target=self._recording, args=(p.webdriver,)).start()
        return self._page

    def stop_record(self):
        self._screen_event.clear()
        self._save_process()
        shutil.rmtree(self._img_dir)

    def __enter__(self) -> BasePage:
        if self._logging_process:
            return self.start_record()
        return self._page

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_tb:
            p.add_screen(exc_val)
        p.quit()
        return self.stop_record()


@pytest.fixture(scope="function", autouse=False)
def init_testplan():
    def _(logging_process=True):
        return TestProcess(BasePage(), logging_process)

    yield _

# @pytest.fixture(scope="session", autouse=True)
# def ding_fixture():
#     yield
#     ap = AllureReport()
#     DingTalk().send_text(
#         f"测试已完成，点此查看测试报告"
#         f"http://{settings.ALLURE_HOST}:{settings.ALLURE_PORT}/index.html#\n"
#         f"通过：  {ap.passed_count}\n"
#         f"失败：  {ap.failed_count}\n"
#         f"异常：  {ap.broken_count}\n"
#         f"跳过：  {ap.skipped_count}\n"
#         f"总计：  {ap.total_count}\n"
#         f"通过率：{ap.pass_rate} %\n"
#         f"执行总时长：{ap.process_duration} 秒")
